#!/usr/bin/env python

from fabric.api import *
from fabric.context_managers import *
from fabric.contrib.console import confirm
from fabric.colors import *

import configparser
import time
import logging
import os
import json


logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# filename = '%s/log/%s.log' % (os.getcwd(),
#                               time.strftime("%Y%m%d", time.localtime()))
# logging.basicConfig(level=logging.INFO,  # 控制台打印的日志级别
#                     filename=filename,
#                     filemode='a',  # 模式，有w和a，w就是写模式，每次都会重新写日志，覆盖之前的日志
#                     format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'
#                     )
logger = logging.getLogger(__name__)

path = '%s/conf/fab.ini' % os.getcwd()
config = configparser.ConfigParser()
config.read(path)
fab_config = config['fab']
host = fab_config['host'] if 'host' in fab_config else '192.168.1.150'
env.hosts = [host]
env.port = int(fab_config['port']) if 'port' in fab_config else 22
env.user = fab_config['user'] if 'user' in fab_config else 'pi'
env.password = fab_config['password'] if 'password' in fab_config else 'raspberry'
local_path = fab_config['local_path'] if 'local_path' in fab_config else 'local_path'
remote_path = fab_config['remote_path'] if 'remote_path' in fab_config else 'remote_path'

# env.hosts = ['192.168.1.150']
# env.user = 'pi'
# env.port = 22
# env.password = 'raspberry'
# local_path = './packages'
# remote_path = '/home/pi/fsc-system'



def setEnv(**kwargs):
    env.hosts = kwargs['host'] if 'host' in kwargs else ['192.168.1.150']
    env.user = kwargs['user'] if 'user' in kwargs else 'pi'
    env.port = int(kwargs['port']) if 'port' in kwargs else 22
    env.password = kwargs['password'] if 'password' in kwargs else 'raspberry'
    local_path = kwargs['local_path'] if 'local_path' in kwargs else './packages'
    remote_path = kwargs['remote_path'] if 'remote_path' in kwargs else '/home/pi/fsc-system'


def fabWriteConfig(**kwargs):
    local_path = kwargs['local_path']
    logger.info(kwargs['host'])
    logger.info(kwargs['user'])
    logger.info(kwargs['port'])
    logger.info(kwargs['password'])
    logger.info(kwargs['local_path'])
    logger.info(kwargs['remote_path'])
    """写入配置文件中"""
    try:
        host = kwargs['host'] if 'host' in kwargs else ['192.168.1.150']
        user = kwargs['user'] if 'user' in kwargs else 'pi'
        port = kwargs['port'] if 'port' in kwargs else '22'
        password = kwargs['password'] if 'password' in kwargs else 'raspberry'
        local_path = kwargs['local_path'] if 'local_path' in kwargs else './packages'
        remote_path = kwargs['remote_path'] if 'remote_path' in kwargs else '/home/pi/fsc-system'
        path = '%s/conf/fab.ini' % os.getcwd()
        logger.info('read config file: %s' % path)
        config = configparser.ConfigParser()
        config.read(path)
        config.set("fab", "hosts", json.dumps([host]))
        config.set("fab", "port", port)
        config.set("fab", "user", user)
        config.set("fab", "password", password)
        config.set("fab", "local_path", local_path)
        config.set("fab", "remote_path", remote_path)
        # 写入并保存文件到当前项目文件夹下
        with open(path, 'w') as fw:
            config.write(fw)
    except Exception as e:
        print(e)

def fabReadConfig():
    # 读取配置文件
    try:
        path = '%s/conf/fab.ini' % os.getcwd()
        config = configparser.ConfigParser()
        config.read(path)
        fab_config = config['fab']
        logger.info('read config file: %s' % path)
        logger.warn('**************FAB READ INFO**************')
        logger.info(fab_config['host'])
        logger.info(fab_config['user'])
        logger.info(fab_config['port'])
        logger.info(fab_config['password'])
        logger.info(fab_config['local_path'])
        logger.info(fab_config['remote_path'])
        logger.warn('**************END**************')
        global local_path
        global remote_path
        env.hosts = [fab_config['host'] if 'host' in fab_config else '192.168.1.150']
        env.port = int(fab_config['port']) if 'port' in fab_config else 22
        env.user = fab_config['user'] if 'user' in fab_config else 'pi'
        env.password = fab_config['password'] if 'password' in fab_config else 'raspberry'
        local_path = fab_config['local_path'] if 'local_path' in fab_config else 'local_path'
        remote_path = fab_config['remote_path'] if 'remote_path' in fab_config else 'remote_path'
        # return hosts, user, port, password, local_path, remote_path
    except Exception as e:
        logger.error(e)

@task                           # 本地打包任务函数，只限执行一次
@runs_once
def tar_task():
    with lcd("/data"):
        local("tar -czf test.tar.gz test.txt")

@task
def put_task(local_path, remote_path):                 # 上传文件任务函数
    # run("mkdir -p /data/logs")
    # with cd("/data/logs"):
    with settings(warn_only=True):  # put（上传）出现异常时继续执行，不终止
        result = put(local_path=local_path, remote_path=remote_path)
    # 出现异常时，确认用户是否继续，（Y继续）
    if result.failed and not confirm("put file failed, Continue[Y/N]?"):
        abort("Aborting file put task!")

# @task
# def check_task():  # 校验文件任务函数
#     with settings(warn_only=True):
#         #本地local命令需要配置capture=True才能捕获返回值
#         lmd5 = local("md5sum /data/test.tar.gz", capture=True).split(' ')[0]
#         rmd5 = run("md5sum /data/logs/test.tar.gz").split(' ')[0]
#     if lmd5 == rmd5:
#         print("OK")
#     else:
#         print("ERROR")

@task
def web():
    fabReadConfig()
    put_task('%s/web.zip' % local_path, remote_path)
    with cd(remote_path):
        # 停止web服务
        run('sudo docker-compose stop web')
        # 解压并覆盖
        run('unzip -o web.zip') 
        # 重新编译镜像
        # run('sudo docker-compose build web')
        # 重启web服务
        run('sudo docker-compose up -d web')
        # 清除所有None镜像
        # run('sudo docker rmi $(sudo docker images -q -f dangling=true)')

@task
def server():
    fabReadConfig()
    put_task('%s/server.zip' % local_path, remote_path)
    with cd(remote_path):
        run('sudo docker-compose stop server')
        run('unzip -o server.zip') 
        run('sudo docker-compose build server')
        run('sudo docker-compose up -d server')
        run('sudo docker rmi $(sudo docker images -q -f dangling=true)')

@task
def mysql():
    fabReadConfig()
    put_task('%s/mysql.zip' % local_path, remote_path)
    with cd(remote_path):
        run('sudo docker-compose stop mysqldb')
        run('unzip -o mysql.zip') 
        run('sudo docker-compose build mysqldb')
        run('sudo docker-compose up -d mysqldb')
        # run('sudo docker rmi $(sudo docker images -q -f dangling=true)')

@task
def emqx():
    fabReadConfig()
    put_task('%s/emqx.zip' % local_path, remote_path)
    with cd(remote_path):
        run('sudo docker-compose stop emqx')
        run('unzip -o emqx.zip') 
        run('sudo docker-compose build emqx')
        run('sudo docker-compose up -d emqx')
        # run('sudo docker rmi $(sudo docker images -q -f dangling=true)')

@task
def docker():
    fabReadConfig()
    put_task('%s/docker-compose.yml' % local_path, remote_path)
    with cd(remote_path):
        run('sudo docker-compose stop')
        run('sudo docker-compose up -d')
        # run('sudo docker rmi $(sudo docker images -q -f dangling=true)')

@task
def up_all():
    fabReadConfig()
    put_task('%s/web.zip' % local_path, remote_path)
    put_task('%s/server.zip' % local_path, remote_path)
    with cd(remote_path):
        # 停止服务
        run('sudo docker-compose stop')
        # 解压并覆盖
        run('unzip -o web.zip') 
        run('unzip -o server.zip') 
        # 重新编译镜像
        run('sudo docker-compose build server')
        # 重启服务
        run('sudo docker-compose up -d')
        # 清除所有None镜像
        run('sudo docker rmi $(sudo docker images -q -f dangling=true)')


@task
def web_bk():
    fabReadConfig()
    filename = 'fsc-system'
    put_task('%s/fsc-system.zip' % local_path, '%s' % remote_path)
    with cd('%s/%s' % (remote_path, filename)):
        run('sudo docker-compose stop ')

    with cd(remote_path):
        print('进入远程目录: %s' % remote_path)
        run('unzip -o %s.zip' % filename) # 解压并覆盖

    with cd('%s/%s' % (remote_path, filename)):
        run('sudo docker-compose up -d')

@task
def server_bk():
    fabReadConfig()
    filename = 'fsc-system'
    put_task('%s/fsc-system.zip' % local_path, '%s' % remote_path)
    with cd('%s/%s' % (remote_path, filename)):
        run('sudo docker-compose stop ')

    with cd(remote_path):
        print('进入远程目录: %s' % remote_path)
        run('unzip -o %s.zip' % filename) # 解压并覆盖

    with cd('%s/%s' % (remote_path, filename)):
        # 构建server
        run('sudo docker-compose build server')
        # 启动
        run('sudo docker-compose up -d')
        # 清除所有None镜像
        run('sudo docker rmi $(sudo docker images -q -f dangling=true)')

@task
def up_all_bk():
    fabReadConfig()
    # filename = 'fsc-system'
    # put_task('%s/fsc-system.zip' % local_path, '%s' % remote_path)
    # with cd(remote_path):
    #     print('进入远程目录: %s' % remote_path)
    #     run('unzip -o %s.zip' % filename) # 解压并覆盖
    # with cd('%s/fsc-system' % remote_path):
    #     run('sudo docker-compose stop ')
    # with cd('%s/%s' % (remote_path, filename)):
    #     run('sudo docker-compose build server')
    #     # 启动
    #     run('sudo docker-compose up -d')
    #     # 清除所有None镜像
    #     run('sudo docker rmi $(sudo docker images -q -f dangling=true)')


